<?php

namespace App\Kuafu\CouponPackage\Service;

use App\Kuafu\Activity\Enum\ActivityEnum;
use App\Kuafu\Activity\Exceptions\ActivityException;
use App\Kuafu\Base\Model\BaseModel;
use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Common\Service\CommonService;
use App\Kuafu\CouponPackage\Enum\CouponPackageCodeEnum;
use App\Kuafu\CouponPackage\Enum\CouponPackageEnum;
use App\Kuafu\CouponPackage\Exceptions\CouponPackageException;
use App\Kuafu\CouponPackage\Model\CouponPackageMappingModel;
use App\Kuafu\CouponPackage\Model\CouponPackageModel;
use App\Kuafu\CouponPackage\Model\CouponPackageOrderModel;
use App\Kuafu\CouponPackage\Model\CouponPackageShopMappingModel;
use App\Kuafu\Customer\Model\CustomerModel;
use App\Kuafu\Customer\Service\CustomerPlatformService;
use App\Kuafu\CustomerCoupon\Exceptions\CustomerCouponException;
use App\Kuafu\CustomerCoupon\Model\CustomerCouponModel;
use App\Kuafu\CustomerCoupon\Service\CustomerCouponService;
use App\Kuafu\Order\Enum\CodeEnum;
use App\Kuafu\Order\Model\OrderExternalSplitModel;
use App\Kuafu\Pay\Model\PayStreamModel;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Service\ShopService;
use App\Kuafu\User\Model\User;
use App\Scope\ShopScope;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;

class CouponPackageService extends BaseService
{

    /**
     * 创建优惠券包
     *
     * @param int $brandId
     * @param array $data
     * @param array $couponPackageMappingParams
     * @param array $couponPackageShopMappingParams
     * @param int $creatorUid
     * @throws CouponPackageException
     */
    public static function create(
        int $brandId,
        array $data,
        array $couponPackageMappingParams,
        array $couponPackageShopMappingParams,
        int $creatorUid
    ) {
        try {
            DB::beginTransaction();

            //新增优惠券包
            $couponPackageId = CouponPackageModel::query()->insertGetId(array_merge($data, [
                'brandId'      => $brandId,
                'startAt'      => strtotime($data['startAt']),
                'endAt'        => strtotime($data['endAt']),
                'createdAt'    => time(),
                'createdByUid' => $creatorUid
            ]));

            //新增优惠券包子表
            $couponPackageMappingInsert = [];
            array_map(function ($couponInfoItem) use (&$couponPackageMappingInsert, $couponPackageId, $creatorUid) {
                array_push($couponPackageMappingInsert, [
                    'couponId'        => $couponInfoItem['id'],
                    'number'          => $couponInfoItem['num'],
                    'couponPackageId' => $couponPackageId,
                    'createdAt'       => time(),
                    'createdByUid'    => $creatorUid
                ]);
            }, $couponPackageMappingParams['couponInfo']);
            CouponPackageMappingModel::query()->insert($couponPackageMappingInsert);

            //新增优惠券包可用门店表
            $couponPackageShopMappingInsert = [];
            array_map(function ($shopId) use (&$couponPackageShopMappingInsert, $couponPackageId, $creatorUid) {
                array_push($couponPackageShopMappingInsert, [
                    'shopId'          => $shopId,
                    'couponPackageId' => $couponPackageId,
                    'createdAt'       => time(),
                    'createdByUid'    => $creatorUid
                ]);
            }, $couponPackageShopMappingParams['shopInfo']);
            CouponPackageShopMappingModel::query()->insert($couponPackageShopMappingInsert);

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_DB_ADD);
        }
    }

    /**
     * 更新优惠券包
     *
     * @param int $brandId
     * @param int $couponPackageId
     * @param array $data
     * @param array $couponPackageMappingParams
     * @param array $couponPackageShopMappingParams
     * @param int $updateUid
     * @throws CouponPackageException
     */
    public static function update(
        int $brandId,
        int $couponPackageId,
        array $data,
        array $couponPackageMappingParams,
        array $couponPackageShopMappingParams,
        int $updateUid
    ) {
        try {
            DB::beginTransaction();

            $couponPackage = CouponPackageModel::query()->find($couponPackageId);
            if (empty($couponPackage)) {
                throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_ID_NOT_EXIST);
            }

            //更新优惠券包
            CouponPackageModel::query()->where('id', $couponPackageId)->update(array_merge($data, [
                'brandId'      => $brandId,
                'startAt'      => strtotime($data['startAt']),
                'endAt'        => strtotime($data['endAt']),
                'updatedAt'    => time(),
                'updatedByUid' => $updateUid
            ]));

            //新增优惠券包子表
            $couponPackageMappingInsert = [];
            CouponPackageMappingModel::query()->where('couponPackageId', $couponPackageId)->delete();
            array_map(function ($couponInfoItem) use (&$couponPackageMappingInsert, $couponPackageId, $updateUid) {
                array_push($couponPackageMappingInsert, [
                    'couponId'        => $couponInfoItem['id'],
                    'number'          => $couponInfoItem['num'],
                    'couponPackageId' => $couponPackageId,
                    'createdAt'       => time(),
                    'updatedByUid'    => $updateUid
                ]);
            }, $couponPackageMappingParams['couponInfo']);
            CouponPackageMappingModel::query()->insert($couponPackageMappingInsert);

            //新增优惠券包可用门店表
            $couponPackageShopMappingInsert = [];
            CouponPackageShopMappingModel::query()->where('couponPackageId', $couponPackageId)->delete();
            array_map(function ($shopId) use (&$couponPackageShopMappingInsert, $couponPackageId, $updateUid) {
                array_push($couponPackageShopMappingInsert, [
                    'shopId'          => $shopId,
                    'couponPackageId' => $couponPackageId,
                    'createdAt'       => time(),
                    'updatedByUid'    => $updateUid
                ]);
            }, $couponPackageShopMappingParams['shopInfo']);
            CouponPackageShopMappingModel::query()->insert($couponPackageShopMappingInsert);

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_DB_SET);
        }
    }

    /**
     * @param $pageNum
     * @param $pageSize
     * @param $brandId
     * @param $name
     * @param $status
     * @param $shopIds
     * @param $createdUserName
     * @return array
     */
    public static function lists(
        $pageNum,
        $pageSize,
        $brandId,
        $name,
        $status,
        $shopIds,
        $createdUserName
    ): array {
        $paginator = CouponPackageModel::query()
//                                    ->withGlobalScope("shopScope",
//                                        new ShopScope(function(Builder $builder){
//                                            $shopType = Shop::query()->whereIn('id', ShopScope::getShopIdsArr())->get()->pluck("type")->toArray();
//                                            $map = [ActivityEnum::SHOP_TYPE_ALL];
//                                            if(count(array_unique($shopType)) == 1){
//                                                array_push($map, $shopType[0]);
//                                            }
//
//                                            $couponPackageIds = CouponPackageShopMappingModel::query()
//                                                ->whereIn("shopId", ShopScope::getShopIdsArr())
//                                                ->get()
//                                                ->groupBy("couponPackageId")
//                                                ->map(function($v, $k){
//                                                    if($v->count() == count(ShopScope::getShopIdsArr())){
//                                                        return $k;
//                                                    }
//                                                    return 0;
//                                                })->filter()->toArray();
//
//                                            $builder->where(function ($query)use($map, $couponPackageIds){
//                                                $query
//                                                    ->orWhereIn('shopType', $map)
//                                                    ->orWhereIn('id', $couponPackageIds);
//                                            });
//                                        }))
                                       ->where('isDeleted', 0)
                                       ->when($name, function (Builder $query) use ($name) {
                                           $query->where('name', 'like', "%{$name}%");
                                       })
                                       ->when(strlen($status) > 0, function (Builder $query) use ($status) {
                                           switch ($status) {
                                               case CouponPackageEnum::STATUS_OFF:
                                               case CouponPackageEnum::STATUS_ON:
                                                   $query
                                                       ->where('startAt', '<', time())
                                                       ->where('endAt', '>', time())
                                                       ->where('status', '=', $status);
                                                   break;
                                               case -1:
                                                   $query->where('endAt', '<', time());
                                                   break;
                                               case -2:
                                                   $query->where('startAt', '>', time());
                                                   break;
                                           }
                                       })
                                        ->when(ShopScope::getShopIdsArr(), function (Builder $query) {
                                                $query->where(function ($query){
                                                    $query
                                                        ->whereHas('couponPackageShopMappingRel', function ($query) {
                                                                $query->whereIn('shopId', ShopScope::getShopIdsArr());
                                                        })
                                                        ->orWhereIn(
                                                            'shopType',
                                                            ShopScope::getShopsType()
                                                                ->unique()
                                                                ->push(CouponPackageEnum::SHOP_TYPE_ALL)
                                                                ->toArray()
                                                        );
                                                });
                                        })
                                       ->when(strlen($createdUserName),
                                           function ($query) use ($createdUserName, $brandId) {
                                               $userIds = User::query()
                                                              ->where('brandId', $brandId)
                                                              ->where('username', 'like', "%{$createdUserName}%")
                                                              ->pluck('id')
                                                              ->toArray();
                                               $query->whereIn('createdByUid', $userIds);
                                           })
                                       ->with([
                                           'couponPackageShopMappingRel' => function (HasMany $query) {
                                               $query->with([
                                                   'shopInfoRel' => function (HasOne $query) {
                                                       $query->select(['id', 'name']);
                                                   }
                                               ])->select(['couponPackageId', 'shopId']);
                                           },
                                           'couponPackageMappingRel'     => function (HasMany $query) {
                                               $query->with([
                                                   'couponInfoRel' => function (HasOne $query) {
                                                       $query->select(['id', 'name']);
                                                   }
                                               ])->select(['couponPackageId', 'couponId']);
                                           },
                                           'createdUser',
                                           'updatedUser'
                                       ])
                                       ->orderBy('createdAt', 'desc')
                                       ->paginate($pageSize, ['*'], 'page', $pageNum);

        return [
            'count'    => $paginator->total(),
            'list'     => array_map(function (CouponPackageModel $v) {
                return [
                    'id'              => $v->id,
                    'name'            => $v->name,
                    'shareTitle'      => $v->shareTitle,
                    'canSaleCount'    => $v->canSaleCount,
                    'hasSaleCount'    => $v->hasSaleCount,
                    'salePrice'       => $v->salePrice,
                    'startAt'         => $v->startAt > 0 ? date('Y-m-d', $v->startAt) : '',
                    'endAt'           => $v->endAt > 0 ? date('Y-m-d', $v->endAt) : '',
                    'status'          => $v->endAt < time() ? -1 : ($v->startAt > time() ? -2 : $v->status),
                    'statusText'      => $v->endAt < time() ? "已到期" : ($v->startAt > time() ? '未开始' : CouponPackageEnum::STATUS_MAP[$v->status]),
                    'shopCanUseTotal' => $v->shopType == CouponPackageEnum::SHOP_TYPE_SELECTION ? $v->couponPackageShopMappingRel ? $v->couponPackageShopMappingRel->count() . '家' : '0家' : CouponPackageEnum::SHOP_TYPES[$v->shopType],
                    'createdAt'       => $v->createdAt->timestamp > 0 ? $v->createdAt->format('Y-m-d H:i:s') : '',
                    'createdUserName' => (string)optional($v->createdUser)->username,
                    'updatedUserName' => (string)optional($v->updatedUser)->username,
                ];
            }, $paginator->items()),
            'pageNum'  => (int)$pageNum,
            'pageSize' => (int)$pageSize,
        ];
    }

    /**
     * 获取券包详情
     *
     * @param int $id
     * @return array
     * @throws CouponPackageException
     */
    public static function row(int $id): array
    {
        try {
            $row = CouponPackageModel::query()
                                     ->where('id', '=', $id)
                                     ->with([
                                         'couponPackageShopMappingRel' => function (HasMany $query) {
                                             $query->with([
                                                 'shopInfoRel' => function (HasOne $query) {
                                                     $query->select(['id', 'name']);
                                                 }
                                             ])->select(['couponPackageId', 'shopId']);
                                         },
                                         'couponPackageMappingRel'     => function (HasMany $query) {
                                             $query->with([
                                                 'couponInfoRel' => function (HasOne $query) {
                                                     $query->select(['id', 'name']);
                                                 }
                                             ])->select(['couponPackageId', 'couponId', 'number']);
                                         },
                                         'createdUser'
                                     ])
                                     ->first();

            if (!$row) {
                throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_ID_NOT_EXIST);
            }

            return [
                'statusMap'                   => CouponPackageEnum::STATUS_MAP,
                'id'                          => $row->id,
                'name'                        => $row->name,
                'shareTitle'                  => $row->shareTitle,
                'dayStartAt'                  => $row->dayStartAt,
                'dayEndAt'                    => $row->dayEndAt,
                'startAt'                     => $row->startAt > 0 ? date('Y-m-d', $row->startAt) : '',
                'endAt'                       => $row->endAt > 0 ? date('Y-m-d', $row->endAt) : '',
                'shopType'                    => $row->shopType,
                'canSaleCount'                => $row->canSaleCount,
                'hasSaleCount'                => $row->hasSaleCount,
                'salePrice'                   => $row->salePrice,
                'shopCanUseTotal'             => $row->shopType == CouponPackageEnum::SHOP_TYPE_SELECTION ? $row->couponPackageShopMappingRel ? $row->couponPackageShopMappingRel->count() . '家' : '0家' : CouponPackageEnum::SHOP_TYPES[$row->shopType],
                'couponPackageShopMappingRel' => $row->couponPackageShopMappingRel ? $row->couponPackageShopMappingRel->map(function (
                    $v
                ) {
                    return [
                        'name' => $v->shopInfoRel ? $v->shopInfoRel->name : null,
                        'id'   => $v->shopInfoRel ? $v->shopInfoRel->id : null,
                    ];
                }) : [],
                'couponPackageMappingRel'     => $row->couponPackageMappingRel->map(function ($v) {
                    return [
                        'name' => $v->couponInfoRel ? $v->couponInfoRel->name : null,
                        'id'   => $v->couponInfoRel ? $v->couponInfoRel->id : null,
                        'num'  => $v->number
                    ];
                })->toArray(),
                'couponPackageImg'            => $row->couponPackageImg ? CommonService::joinImageUrl($row->couponPackageImg) : '',
                'miniAdvPopSwitch'            => $row->miniAdvPopSwitch,
                'miniAdvPopImg'               => $row->miniAdvPopImg ? CommonService::joinImageUrl($row->miniAdvPopImg) : '',
                'bannerImg'                   => $row->bannerImg ? CommonService::joinImageUrl($row->bannerImg) : '',
                'detailImg'                   => $row->detailImg ? CommonService::joinImageUrl($row->detailImg) : '',
                'collectMoneyCopy'            => $row->collectMoneyCopy,
                'publicityCopy'               => $row->publicityCopy,
                'popDate'                     => $row->popDate,
                'noticeOfPurchase'            => $row->noticeOfPurchase,
                'noticeOfPurchaseDetail'      => $row->noticeOfPurchaseDetail,
                'status'                      => $row->endAt < time() ? -1 : ($row->startAt > time() ? -2 : $row->status),
                'statusText'                  => $row->endAt < time() ? "已到期" : ($row->startAt > time() ? "未开始" : CouponPackageEnum::STATUS_MAP[$row->status]),
                'createdAt'                   => $row->createdAt->timestamp > 0 ? $row->createdAt->format('Y-m-d H:i:s') : '',
                'createdUserName'             => (string)optional($row->createdUser)->username,
            ];
        } catch (CouponPackageException $e) {
            throw $e;
        }
    }

    /**
     * 修改券包状态
     *
     * @param int $id
     * @param int $status
     * @throws ActivityException
     */
    public function setStatus(int $id, int $status)
    {
        try {
            DB::beginTransaction();
            if (!in_array($status, array_keys(CouponPackageEnum::STATUS_MAP))) {
                throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_PARAM_VALID);
            }
            $couponPackageInfo = CouponPackageModel::query()->where('id', '=', $id)->first();
            if (empty($couponPackageInfo)) {
                throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_ID_NOT_EXIST);
            }

            if ($couponPackageInfo->status == $status) {
                throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_REPEATED_OPERATE);
            }

            $couponPackageInfo->status = $status;
            $couponPackageInfo->save();
            DB::commit();
        } catch (CouponPackageException $e) {
            DB::rollBack();
            throw $e;
        }
    }

    public static function dateToChangeCouponPackaggeList($packageId)
    {
        $info                 = self::getCouponPackageInfoById($packageId)->toArray();
        $canUseCouponList     = [];
        $i                    = 0;
        $couponPackageMapping = array_column($info['coupon_package_mapping_rel'], null, 'couponId');
        $couponList           = $info['coupon_package_mapping_info_rel'];
        $shopRel              = $info['coupon_package_shop_mapping_rel'];
        foreach ($couponList as $item => $value) {
            $canUseCouponList[$i]               = $value;
            $canUseCouponList[$i]['couponId']   = $value['id'];
            $canUseCouponList[$i]['shopType']   = $info['shopType'];
            $canUseCouponList[$i]['activityId'] = $info['id'];
            $canUseCouponList[$i]['number']     = $couponPackageMapping[$value['id']]['number'];
            $canUseCouponList[$i]['shopRel']    = $shopRel;
            $canUseCouponList[$i]['createdAt']  = date('Y-m-d H:i:s', time() - 1);
            $i++;
        }
        return $canUseCouponList;
    }

    public static function getCouponPackageInfoById($packageId)
    {
        return CouponPackageModel::getCouponPackageInfoById($packageId);
    }

    /**
     * 购买券包预检查
     * @param int $id
     * @param int $shopId
     * @param int $userId
     * @throws CouponPackageException
     */
    public static function checkBuy(int $id, int $shopId, int $userId)
    {
        $cp = CouponPackageModel::query()->where('id', $id)->first();
        if (!$cp) {
            throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_ID_NOT_EXIST);
        }

        // 检查售卖时间
        if ($cp->startAt > time()) {
            throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_NOT_STARTED);
        }
        if ($cp->endAt < time()) {
            throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_ENDED);
        }

        // 检查券包状态
        if ($cp->status != CouponPackageEnum::STATUS_ON) {
            throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_STATUS_DOWN);
        }

        // 检查券包库存
        if ($cp->canSaleCount <= 0) {
            throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_STOCK_EMPTY);
        }

        // 检查店铺映射
        if ($cp->shopType != CouponPackageEnum::SHOP_TYPE_ALL) {

            // 部分选择
            if ($cp->shopType == CouponPackageEnum::SHOP_TYPE_SELECTION) {
                $shopMaps = CouponPackageShopMappingModel::query()
                                                         ->where('shopId', $shopId)
                                                         ->where('couponPackageId', $id)
                                                         ->count();
                if (!$shopMaps) {
                    throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_NO_SHOP_MAP);
                }
            }

            // 店铺类型限制
            if (in_array($cp->shopType,
                [CouponPackageEnum::SHOP_TYPE_FRANCHISE, CouponPackageEnum::SHOP_TYPE_DIRECT])) {
                $dbShopType = ShopService::getShopInfo($shopId)->type ?? 0;
                if ($dbShopType != $cp->shopType) {
                    throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_NO_SHOP_MAP);
                }
            }
        }

        // 不用检查 - 检查用户是否购买过
//        $checkOrder = CouponPackageOrderModel::checkBuyOrder($userId, $id);
//        if ($checkOrder) {
//            throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_HAS_BUY);
//        }

        return $cp;
    }

    /**
     * 购买
     * @param int $id
     * @param int $shopId
     * @param int $brandId
     */
    public static function doBuy(int $couponPackageId, int $shopId, int $userId): array
    {
        $brandId = ShopService::getShopInfo($shopId)->brandId ?? 0;

        // 预检查
        $cp = self::checkBuy($couponPackageId, $shopId, $userId);

        try {

            DB::beginTransaction();

            // 先锁定库存，库存不足会抛出异常
            CouponPackageModel::decrStock($couponPackageId);

            $cpStock = CouponPackageModel::query()
                                         ->where('id', $couponPackageId)
                                         ->value('canSaleCount') ?? 0;

            // 当库存清0的时候，把状态禁用了
            if ($cpStock <= 0) {
                CouponPackageModel::banStatus($couponPackageId);
            }

            // 生成订单
            $sourceType  = CodeEnum::SOURCE_TYPE_MINI;
            $payPrice    = $cp->salePrice;
            $shopIncomes = $cp->salePrice;

            $orderId = CouponPackageOrderModel::addData($brandId, $shopId, $userId, $couponPackageId, $sourceType,
                $payPrice, $shopIncomes, 0, 0);

            DB::commit();

        } catch (\Exception $e) {
            Log::warning($e);
            DB::rollBack();
            throw new CouponPackageException(CouponPackageCodeEnum::ERR_COUPON_PACKAGE_BUY_ERROR, '', $e);
        }

        return [$orderId, $payPrice];
    }

    /**
     * 获取券包销售详情
     * @param $couponPackageId
     * @param $name
     * @param $phone
     * @param $shopId
     * @param $startAt
     * @param $endAt
     * @param $pageNum
     * @param $pageSize
     * @return array
     */
    public static function packageDetail(
        $couponPackageId,
        $name,
        $phone,
        $shopId,
        $startAt,
        $endAt,
        $pageNum = 1,
        $pageSize = -1
    ) {
        // 为payStreamRel服务
        (new BaseModel())->setSplitShopId($shopId);

        $lists = CouponPackageOrderModel::query()
                                        ->where('payStatus', CouponPackageEnum::PAY_STATUS_ON)
                                        ->with(['customerRel', 'shopRel', 'couponPackageRel', 'payStreamRel'])
                                        ->when($couponPackageId, function ($query) use ($couponPackageId) {
                                            $query->where('couponPackageId', $couponPackageId);
                                        })
                                        ->when($name, function ($query) use ($name) {
                                            $couponPackageIds = CouponPackageModel::query()
                                                                                  ->where('status',
                                                                                      CouponPackageEnum::STATUS_ON)
                                                                                  ->where('name', 'like', "%$name%")
                                                                                  ->pluck('id');
                                            $query->whereIn('couponPackageId', $couponPackageIds);
                                        })
                                        ->when($phone, function ($query) use ($phone) {
                                            $userIds = CustomerModel::query()
                                                                    ->where('mobile', 'like', "$phone")
                                                                    ->pluck('id');

                                            $query->whereIn('userId', $userIds);
                                        })
                                        ->when($shopId, function ($query) use ($shopId) {
                                            $query->where('shopId', $shopId);
                                        })
                                        ->when($startAt, function ($query) use ($startAt, $endAt) {
                                            $query->whereBetween('createdAt',
                                                [strtotime($startAt), strtotime($endAt)]);
                                        });
        if ($pageSize != -1) {
            $lists             = $lists->paginate($pageSize, ['*'], 'pageNum', $pageNum);
            $couponPackageList = $lists->items();
        } else {
            $couponPackageList = $lists->get();
        }
        $data       = [];
        $noStreamId = [];
        foreach ($couponPackageList as $k => $list) {
            if ($list->createdAt instanceof Carbon) {
                $date = $list->createdAt->toDateTimeString();
            } else {
                $date = Carbon::createFromTimestamp($list->createdAt)
                              ->toDateTimeString();
            }
            $data[$k]['couponPackageId']   = $list->couponPackageId;
            $data[$k]['couponPackageName'] = $list->couponPackageRel->name ?? '';
            $data[$k]['shopName']          = $list->shopRel->name ?? '';
            $data[$k]['price']             = $list->payPrice;
            $data[$k]['shopIncome']        = $list->shopIncomes;
            $data[$k]['payStream']         = $list->payStreamRel ? ($list->payStreamRel->first()->payNo ?? '') : '';
            $data[$k]['salesAt']           = $date;
            $data[$k]['userId']            = $list->userId;
            $data[$k]['orderId']           = $list->orderId;
            if ($list->customerRel) {
                $data[$k]['phone'] = substr_replace($list->customerRel->mobile, '****', 3, 4);
            } else {
                $data[$k]['phone'] = '';
            }

            if (empty($list->payStreamRel->payNo)) {
                $noStreamId[] = $list->orderId;
            }
        }
        if (count($noStreamId)) {
            $orderIdList  = (OrderExternalSplitModel::suffix($shopId)->query()->whereIn('extOrderId', $noStreamId)
                                                    ->get()
                                                    ->pluck('orderId',
                                                        'extOrderId')) ? OrderExternalSplitModel::suffix($shopId)
                                                                                                ->query()
                                                                                                ->whereIn('extOrderId',
                                                                                                    $noStreamId)->get()
                                                                                                ->pluck('orderId',
                                                                                                    'extOrderId')
                                                                                                ->toArray() : [];
            $paySteamList = PayStreamModel::suffix($shopId, PayStreamModel::SYS_TYPE_RMS_COUPON_PACKAGE)
                                          ->whereIn('orderId', $orderIdList)->get()->toArray();
            foreach ($paySteamList as &$value) {
                foreach ($orderIdList as $k => $item) {
                    if ($item == $value['orderId']) {
                        $value['couponPackageOrderId'] = $k;
                    }
                }
            }
            foreach ($data as &$item) {
                foreach ($paySteamList as $v) {
                    if ($item['orderId'] == $v['couponPackageOrderId']) {
                        $item['payStream'] = $v['payNo'];
                    }
                }
            }
        }
        if ($pageSize != -1) {
            return [
                'pageNum'   => $lists->currentPage(),
                'pageSize'  => $lists->perPage(),
                'pageCount' => $lists->lastPage(),
                'count'     => $lists->total(),
                'list'      => $data,
            ];
        } else {
            return $data;
        }


    }

    public static function detailExport($couponPackageId, $name, $phone, $shopId, $startAt, $endAt)
    {
        $spreadsheet = new Spreadsheet();
        $sheet       = $spreadsheet->getActiveSheet();

        $sheet->setCellValue('A1', '券包销售记录');
        $sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
        $sheet->getStyle('A1')->getFont()->setSize(16);
        $sheet->mergeCells("A1:H1");

        $headers = [
            '券包名称',
            '用户ID',
            '手机号',
            '售卡门店',
            '券包售价/元',
            '门店分账/元',
            '购买券包时间',
            '支付流水号',
        ];
        $column  = 1;
        foreach ($headers as $header) {
            $sheet->setCellValueExplicit(Coordinate::stringFromColumnIndex($column) . '2', $header,
                DataType::TYPE_STRING);
            $sheet->getStyle(Coordinate::stringFromColumnIndex($column) . '2')->getAlignment()
                  ->setHorizontal(Alignment::HORIZONTAL_CENTER);
            $sheet->getColumnDimension(Coordinate::stringFromColumnIndex($column))->setWidth(35);
            $sheet->getStyle(Coordinate::stringFromColumnIndex($column) . '2')->getFont()->setSize(14);
            $column++;
        }
        $lists = self::packageDetail($couponPackageId, $name, $phone, $shopId, $startAt, $endAt);
        $data  = [];
        foreach ($lists as $k => $v) {
            $data[$k]['couponPackageName'] = $v['couponPackageName'];
            $data[$k]['userId']            = $v['userId'];
            $data[$k]['phone']             = $v['phone'];
            $data[$k]['shopName']          = $v['shopName'];
            $data[$k]['price']             = round((int)$v['price'] / 100, 2);
            $data[$k]['shopIncome']        = round((int)$v['shopIncome'] / 100, 2);
            $data[$k]['salesAt']           = $v['salesAt'];
            $data[$k]['payStream']         = $v['payStream'];
        }
        $count = count($data);
        for ($i = 0; $i < $count; $i++) {
            $column1 = 1;
            foreach ($data[$i] as $list) {
                $sheet->setCellValueExplicit(Coordinate::stringFromColumnIndex($column1) . (3 + $i), $list,
                    DataType::TYPE_STRING);
                $sheet->getStyle(Coordinate::stringFromColumnIndex($column1) . (3 + $i))->getAlignment()
                      ->setHorizontal(Alignment::HORIZONTAL_CENTER);
                $sheet->getStyle(Coordinate::stringFromColumnIndex($column1) . (3 + $i))->getFont()->setSize(14);
                $column1++;
            }
        }
        $tmpFile = sys_get_temp_dir() . "/券包销售列表" . date('YmdHis') . '.xlsx';
        IOFactory::createWriter($spreadsheet, 'Xlsx')->save($tmpFile);
        return $tmpFile;
    }

    /**
     * 获取banner优惠券包
     *
     * @param int $brandId
     * @param int $shopId
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public static function getShopBanner(int $brandId, int $shopId)
    {
        $shop     = ShopService::getShopInfo($shopId);
        $shopType = $shop->type;

        return CouponPackageModel::query()
                                 ->where('brandId', $brandId)
                                 ->where('status', CouponPackageEnum::STATUS_ON)
                                 ->where('startAt', '<=', time())
                                 ->where('endAt', '>=', time())
                                 ->where(function ($query) use ($shopType, $shopId) {
                                     $query->whereIn('shopType',
                                         [CouponPackageEnum::SHOP_TYPE_ALL, $shopType])
                                           ->orWhereHas('couponPackageShopMappingRel',
                                               function ($query) use ($shopId) {
                                                   $query->where('shopId', $shopId);
                                               });
                                 })
                                 ->orderBy('id', 'desc')
                                 ->get();

    }

    /**
     * 购买券包操作
     *
     * @param $packageId
     * @param $userId
     * @param array $checkCoupon 提前需要核销的券信息
     * @param int $shopId
     * @param string $couponPackageOrderId
     * @return array
     * @throws CustomerCouponException
     */
    public static function finished($packageId, $userId, array $checkCoupon = [], int $shopId = 0, string $couponPackageOrderId = '')
    {
        // 增加券的销量
        CouponPackageModel::incrSales($packageId);

        // 发券
        $return = CustomerCouponService::buyCouponPackageSendCoupon($packageId, $userId,
            ActivityEnum::TYPE_COUPON_PACKAGE,
            $checkCoupon, $shopId, $couponPackageOrderId);

        return $return;
    }


    /**
     *
     * 获取可用优惠券列表
     *
     * @param $brandId
     * @param $shopId
     * @param $productList
     * @param $source
     * @param $couponPackageId
     * @return array|mixed
     */
    public static function getEnableCouponList($brandId, $shopId, $productList, $source, $couponPackageId)
    {
        //查询传递过来的优惠券信息
        $canUseCouponService = new CouponPackageEnableCouponService(
            $brandId, $shopId, $productList, $source, $couponPackageId);

        $result = $canUseCouponService->filterCouponPackageCoupon();

        return [
            'enable'  => $result->getCanUseCouponList(),
            'disable' => $result->getCanNotUseCouponList()
        ];

    }


    public static function getOrderDetailByOrderId($orderId)
    {
        return CouponPackageOrderModel::query()->where('orderId', '=', $orderId)->with('couponPackageRel')->first();
    }

    public static function getOrderPackageOrderPrice()
    {

    }
}
